/**
 * jims
 */
package com.jims.master.modules.finance.service;

import com.jims.master.common.persistence.Page;
import com.jims.master.common.service.CrudService;
import com.jims.master.common.utils.DateUtils;
import com.jims.master.common.utils.PrintPdfUtils;
import com.jims.master.common.utils.StringUtils;
import com.jims.master.common.web.impl.BaseDto;
import com.jims.master.modules.doctor.dao.ClinicMasterDao;
import com.jims.master.modules.doctor.entity.ClinicMaster;
import com.jims.master.modules.finance.dao.*;
import com.jims.master.modules.finance.entity.*;
import com.jims.master.modules.sys.dao.CompanyDao;
import com.jims.master.modules.sys.entity.User;
import com.jims.master.modules.sys.utils.UserUtils;
import com.jims.master.modules.utils.NumberToCN;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Service
 * @author chentao
 * @version 2017-03-14
 */
@Service
@Transactional(readOnly = true)
public class OutpAcctMasterService extends CrudService<OutpAcctMasterDao, OutpAcctMaster> {
	@Autowired
	private OutpRcptMasterDao outpRcptMasterDao;
	@Autowired
	private OutpPaymentsMoneDao outpPaymentsMoneDao;
	@Autowired
	private OutpBillItemsDao outpBillItemsDao;
	@Autowired
    private OutpAcctMoneyDao outpAcctMoneyDao;
	@Autowired
	private OutpAcctDetailDao outpAcctDetailDao;
	@Autowired
	private ClinicMasterDao clinicMasterDao;
	@Autowired
	private RegistCostDao registCostDao;
	@Autowired
	private CompanyDao companyDao;

	public OutpAcctMaster get(String id) {
		return super.get(id);
	}
	
	public List<OutpAcctMaster> findList(OutpAcctMaster outpAcctMaster) {
		return super.findList(outpAcctMaster);
	}
	
	public Page<OutpAcctMaster> findPage(Page<OutpAcctMaster> page, OutpAcctMaster outpAcctMaster) {
		return super.findPage(page, outpAcctMaster);
	}

	/**
	 * 门诊结账--结账确认
	 * @param outpAcctMaster
	 * @return int
	 * @author 赵宁
	 */
	@Transactional(readOnly = false)
	public int save(OutpAcctMaster outpAcctMaster) {
		int code=0;
		if(outpAcctMaster!=null){
            if(outpAcctMaster.isOneCard()){
                outpAcctMaster.setCardFlag("1");
            }else{
                outpAcctMaster.setCardFlag("0");
            }
			OutpAcctMaster acctMaster = dao.getAcctInfo(outpAcctMaster);
			acctMaster.setAcctNo(outpAcctMaster.getAcctNo());
			acctMaster.setAcctStartDate(DateUtils.parseDate(outpAcctMaster.getStartTime()));
			acctMaster.setAcctEndDate(DateUtils.parseDate(outpAcctMaster.getEndTime()));
			acctMaster.setAcctType("1");
			code=super.save(acctMaster);//插入结账主记录
			List<OutpPaymentsMone> paymentsMones= outpPaymentsMoneDao.getPayments(outpAcctMaster);
			if(paymentsMones!=null && paymentsMones.size()>0){
				for(int i=0;i<paymentsMones.size();i++){
					OutpAcctMoney outpAcctMoney = new OutpAcctMoney();
					outpAcctMoney.preInsert();
					outpAcctMoney.updateOrgId();
					outpAcctMoney.setAcctNo(acctMaster.getAcctNo());
					outpAcctMoney.setAcctId(acctMaster.getId());
					outpAcctMoney.setMoneyType(paymentsMones.get(i).getMoneyType());
					outpAcctMoney.setCharges(paymentsMones.get(i).getCharges());
					outpAcctMoney.setRefundAmount(paymentsMones.get(i).getRefundCharges());
					outpAcctMoneyDao.insert(outpAcctMoney);//插入结账方式
				}
			}
			List<OutpBillItems> billItemses=outpBillItemsDao.findItems(outpAcctMaster);
			if(billItemses!=null && billItemses.size()>0){
				for(int j=0;j<billItemses.size();j++){
					OutpAcctDetail outpAcctDetail=new OutpAcctDetail();
					outpAcctDetail.preInsert();
					outpAcctDetail.updateOrgId();
					outpAcctDetail.setAcctId(acctMaster.getId());
					outpAcctDetail.setAcctNo(acctMaster.getAcctNo());
					outpAcctDetail.setCosts(billItemses.get(j).getCharges());
					outpAcctDetail.setSubjCode(billItemses.get(j).getSubjCode());
					outpAcctDetailDao.insert(outpAcctDetail);//插入结账详情
				}
			}
            //更新 收费主记录
            outpRcptMasterDao.updateRcptAcctNo(outpAcctMaster);
		}
		return code;
	}
	
	@Transactional(readOnly = false)
	public int delete(OutpAcctMaster outpAcctMaster) {
		return super.delete(outpAcctMaster);
	}

	/**
	 * 获取最大的acctNo
	 * @return String
	 * @author 赵宁
	 */
	public String getMaxAcctNo(){
      String acctNo=dao.getMaxAcctNo();
      if(StringUtils.isNotBlank(acctNo)&& acctNo!=null){
		  int no= Integer.parseInt(acctNo)+1;
		  acctNo = String.valueOf(no);
	  }else{
		  acctNo=""+28000;
	  }
		return acctNo;
	}

	/**
	 * 查询出当前登录人最大结账时间
	 * @param user
	 * @return String
	 * @author 赵宁
	 */
    public String getMaxAcctDate(User user){
		return  dao.getMaxAcctDate(user);
	}
	/**
	 * 查询结账信息
	 * @param outpAcctMaster
	 * @return OutpAcctMaster
	 * @author 赵宁
	 */
	public OutpAcctMaster getAcctInfo(OutpAcctMaster outpAcctMaster){
      return dao.getAcctInfo(outpAcctMaster);
	}
	/**
	 * 挂号结账---结账确认
	 * @param clinicMaster
	 * @param clinicMasters
	 * @return int
	 * @author 赵宁
	 */
	@Transactional(readOnly = false)
	public int saveAcct(ClinicMaster clinicMaster,List<ClinicMaster> clinicMasters,String maxAcctNo,List<RegistCost> registCosts) {
		int result = 0;
		clinicMaster.setAcctNo(maxAcctNo);
		clinicMasterDao.saveAcctNo(clinicMaster);//更新Clinic_master acctNo
		registCostDao.updateRegistAcctNo(clinicMaster);//更新regist_cost
		OutpAcctMaster outpAcctMaster=new OutpAcctMaster();
		outpAcctMaster.updateOrgId();
		outpAcctMaster.preInsert();
		outpAcctMaster.setAcctNo(maxAcctNo);
		outpAcctMaster.setRcptsNum(clinicMaster.getRegistCount() + "");
		outpAcctMaster.setRefundNum(clinicMaster.getBackCount() + "");
		outpAcctMaster.setSumAmount(clinicMaster.getTotalCost());
		outpAcctMaster.setRefundAmount(clinicMaster.getBaclTotalCost());
		outpAcctMaster.setChargesAmount(clinicMaster.getTotalReceipts());
		outpAcctMaster.setAcctStartDate(DateUtils.parseDate(clinicMaster.getCheckStartTime()));
		outpAcctMaster.setAcctEndDate(DateUtils.parseDate(clinicMaster.getCheckEndTime()));
		outpAcctMaster.setAcctType("0");
		result=dao.insert(outpAcctMaster);
		if(clinicMasters!=null && clinicMasters.size()>0){
			for(int i=0;i<clinicMasters.size();i++){
				OutpAcctMoney outpAcctMoney = new OutpAcctMoney();
				outpAcctMoney.preInsert();
				outpAcctMoney.updateOrgId();
				outpAcctMoney.setAcctNo(maxAcctNo);
				outpAcctMoney.setAcctId(outpAcctMaster.getId());
				outpAcctMoney.setMoneyType(clinicMasters.get(i).getType());
				outpAcctMoney.setCharges(clinicMasters.get(i).getClinicChage());
				outpAcctMoney.setRefundAmount(clinicMasters.get(i).getBackChage());
				outpAcctMoneyDao.insert(outpAcctMoney);//插入结账方式
			}
		}
        if(registCosts!=null&&registCosts.size()>0){
			 for(int j=0;j<registCosts.size();j++){
				 OutpAcctDetail outpAcctDetail=new OutpAcctDetail();
				 outpAcctDetail.preInsert();
				 outpAcctDetail.updateOrgId();
				 outpAcctDetail.setAcctId(outpAcctMaster.getId());
				 outpAcctDetail.setAcctNo(maxAcctNo);
				 outpAcctDetail.setCosts(registCosts.get(j).getCost());
				 outpAcctDetail.setSubjCode(registCosts.get(j).getSubjCode());
				 outpAcctDetailDao.insert(outpAcctDetail);//插入结账详情
			 }
		}
		return result;
	}

	/**
	 * 合并结账查询信息
	 * @param outpAcctMaster
	 * @return OutpAcctMaster
	 * @author 赵宁
	 */
    public OutpAcctMaster mergeAcctGetInfo(OutpAcctMaster outpAcctMaster){
		 return dao.mergeAcctGetInfo(outpAcctMaster);
	}

	/**
	 * 合并结账查询支付方式信息
	 * @param outpAcctMaster
	 * @return
	 * @author 赵宁
	 */
	public List<OutpPaymentsMone> mergeAcctGetPayInfo(OutpAcctMaster outpAcctMaster){
		return dao.mergeAcctGetPayInfo(outpAcctMaster);
	}



	/**
	 * 合并结账保存结账信息
	 * @param outpAcctMaster
	 * @return int
	 * @author 赵宁
	 */
	@Transactional(readOnly = false)
	public int mergeAcctSaveInfo(OutpAcctMaster outpAcctMaster){
		int code=0;
        //挂号结账
        code+=this.mergerRegistAcct(outpAcctMaster);
		//门诊收费结账
        code+=this.mergerOutpAcct(outpAcctMaster);
		return code;
	}

	/**
	 * 合并结账挂号信息
	 * @return
	 * @author 赵宁
	 */
	@Transactional(readOnly = false)
	public int mergerRegistAcct(OutpAcctMaster outpAcctMaster){
		int code=0;
		User user = UserUtils.getUser();
		user.setType("0");
		String maxAcctNo = this.getMaxAcctNo();
		String maxAcctDate = dao.getMaxAcctDate(user);//获取结账最大日期
		if(maxAcctDate==null || maxAcctDate.equals("")){
			ClinicMaster clinicMaster = new ClinicMaster();
			clinicMaster.setCreateBy(UserUtils.getUser());
			maxAcctDate=clinicMasterDao.getMinRegistDate(clinicMaster);
		}
		ClinicMaster clinicMaster = new ClinicMaster();
		clinicMaster.setCheckStartTime(maxAcctDate);
		clinicMaster.setCheckEndTime(outpAcctMaster.getEndTime());
        if(outpAcctMaster.isOneCard()){
            clinicMaster.setCardFlag("1");
            clinicMaster.setType("0");
        }else{
            clinicMaster.setCardFlag("0");
            clinicMaster.setCreateBy(UserUtils.getUser());
            clinicMaster.setType("1");
        }
 		ClinicMaster master=clinicMasterDao.clinicCheckout(clinicMaster);
		master.setCheckStartTime(maxAcctDate);
		master.setCheckEndTime(outpAcctMaster.getEndTime());
		List<RegistCost> registCostList = registCostDao.getRegistCosts(clinicMaster);
		List<ClinicMaster> clinicMasters = clinicMasterDao.findCharges(clinicMaster);
		if(clinicMasters.size()>0){
		 code=this.saveAcct(master,clinicMasters,maxAcctNo,registCostList);
		}
		return code;
	}

	/**
	 * 合并结账门诊收费信息
	 * @return
	 * @author 赵宁
	 */
	@Transactional(readOnly = false)
	public int mergerOutpAcct(OutpAcctMaster outpAcctMaster){
		int code=0;
		User user=UserUtils.getUser();
		user.setType("1");
		String acctNo=this.getMaxAcctNo();
		String maxAcctDate = dao.getMaxAcctDate(user);
		if(maxAcctDate==null || maxAcctDate.equals("")){
			OutpRcptMaster outpRcptMaster = new OutpRcptMaster();
			outpRcptMaster.setCreateBy(UserUtils.getUser());
			maxAcctDate=outpRcptMasterDao.getMinRcptDate(outpRcptMaster);
		}
		outpAcctMaster.setAcctNo(acctNo);
		outpAcctMaster.setStartTime(maxAcctDate);
		outpAcctMaster.setCreateBy(user);
		List<OutpPaymentsMone> paymentsMones= outpPaymentsMoneDao.getPayments(outpAcctMaster);
		if(paymentsMones.size()>0){
			code=this.save(outpAcctMaster);
		}
		return code;
	}
	/**
	 * 门诊结账查询打印(1号)
	 * @param outpAcctMaster
	 * @return String
	 * @author 赵宁
	 */
	public String clinicAcctSearchPrint(OutpAcctMaster outpAcctMaster){
		User user = UserUtils.getUser();
		Map map = new HashMap();
		List<BaseDto> list=new ArrayList<BaseDto>();
		String hospital = companyDao.get(user.getOrgId()).getOrgName();
		String printPath="";
		//查询结账主记录
		OutpAcctMaster acctMaster =  dao.getAcctMasterInfo(outpAcctMaster);
		if(acctMaster!=null && acctMaster.getId()!=null){
            ClinicMaster  clinicMaster=clinicMasterDao.printStatisRegistCount(acctMaster.getAcctNo());
			map.put("registNum",clinicMaster.getRegistCount());
			map.put("refundNum",clinicMaster.getBackCount());
			map.put("acctNo",acctMaster.getAcctNo());
			map.put("operator",acctMaster.getCreateBy().getName());
			map.put("printDate", DateUtils.getDateTime());
			map.put("acctDate",DateUtils.formatDateTime(acctMaster.getCreateDate()));
			map.put("inviceStart","");
			map.put("inviceEnd","");
			map.put("inviceCount",acctMaster.getRcptsNum());
			map.put("backInvoice",acctMaster.getRefundNum());
			map.put("refundAmount",acctMaster.getRefundAmount());
			map.put("totalPrice",acctMaster.getSumAmount());
			map.put("receipts",acctMaster.getChargesAmount());
			map.put("cost",acctMaster.getSumAmount());//合计
			BigDecimal numberOfMoney = new BigDecimal(acctMaster.getSumAmount());
			String s = NumberToCN.number2CNMontrayUnit(numberOfMoney);
			map.put("bigCharges",s.toString());
			map.put("inviceDateStart","");
			map.put("inviceDateEnd","");
			map.put("printCreateBy",UserUtils.getUser().getName());
			map.put("rcptDate","");
			map.put("hospital",hospital);
			OutpAcctDetail outpAcctDetail= new OutpAcctDetail();
			outpAcctDetail.setAcctId(acctMaster.getId());
			list=outpAcctDetailDao.findAcctDetails(outpAcctDetail);
		}
		if(outpAcctMaster.getAcctType()!=null && outpAcctMaster.getAcctType().equals("0 ")){//挂号结账打印
			printPath = PrintPdfUtils.previewPdf(user.getId(), "his/finance/registAcctMaster.jasper", map, list, "acct");
		}else{
			printPath = PrintPdfUtils.previewPdf(user.getId(), "his/clinicAcct.jasper", map, list, "acct");
		}

		return printPath;
	}

	/**
	 * 挂号结账打印
	 * @param outpAcctMaster
	 * @return
	 * @author 赵宁
	 */
	public String registAcctPrint(OutpAcctMaster outpAcctMaster){
		User user = UserUtils.getUser();
		Map map = new HashMap();
		List<BaseDto> list=new ArrayList();
		String hospital = companyDao.get(user.getOrgId()).getOrgName();
		String printPath="";
		//查询结账主记录
		OutpAcctMaster acctMaster =  dao.getAcctMasterInfo(outpAcctMaster);
		if(acctMaster!=null && acctMaster.getId()!=null){
			ClinicMaster  clinicMaster=clinicMasterDao.printStatisRegistCount(acctMaster.getAcctNo());
			map.put("registNum",clinicMaster.getRegistCount());
			map.put("refundNum",clinicMaster.getBackCount());
			map.put("acct_no",acctMaster.getAcctNo());
			map.put("operator",acctMaster.getCreateBy().getName());
			map.put("printDate", DateUtils.getDateTime());
			map.put("acctDate",DateUtils.formatDateTime(acctMaster.getCreateDate()));
			map.put("inviceStart","");
			map.put("inviceEnd","");
			map.put("inviceCount",acctMaster.getRcptsNum());
			map.put("backInvoice",acctMaster.getRefundNum());
			map.put("refundAmount",acctMaster.getRefundAmount());
			map.put("totalPrice",acctMaster.getSumAmount());
			map.put("totalCharges",acctMaster.getChargesAmount());
			BigDecimal numberOfMoney = new BigDecimal(acctMaster.getChargesAmount());
			String s = NumberToCN.number2CNMontrayUnit(numberOfMoney);
			map.put("bigCharges",s.toString());
			map.put("inviceDateStart","");
			map.put("inviceDateEnd","");
			map.put("printCreateBy",UserUtils.getUser().getName());
			map.put("rcptDate","");
			map.put("hospital",hospital);
			OutpAcctMoney outpAcctMoney = new OutpAcctMoney();
			outpAcctMoney.setAcctId(acctMaster.getId());
			list=outpAcctMoneyDao.printSearchPay(outpAcctMoney);
			OutpAcctDetail outpAcctDetail= new OutpAcctDetail();
			outpAcctDetail.setAcctId(acctMaster.getId());
			map.put("SUBREPORT_DIR","his/finance/registAcct_subreport1.jasper");
			List<BaseDto> detials=outpAcctDetailDao.findAcctDetails(outpAcctDetail);
			map.put("detials",detials);
		}
		printPath = PrintPdfUtils.previewPdf(user.getId(), "his/finance/registAcct.jasper", map, list, "acct");
		return printPath;
	}
}